﻿#ifndef GAME_H
#define GAME_H

#include "Game/Player.h"


#include "_Global/GameModel.h"
#include "_Global/Sqlite/Sqlite.h"
#include "_Global/Socket/Common.h"


#include <QThread>
#include <QWaitCondition>
#include <QMutex>
#include <QList>
#include <QQueue>
#include <QByteArray>
#include <QDebug>


//#define WAIT_GAME_TERMINATE_TIME 5000


class TcpSocket;
class Game : public GameModel
{
    Q_OBJECT
    Q_PROPERTY(QObject* socketInfo READ socketInfo)

    //Q_PROPERTY(type name READ name WRITE setName NOTIFY nameChanged)

    Q_PROPERTY(QObjectList testList READ testList)


public:


//本类发出的信号
signals:
    //socket发送数据(主线程发送)
    void s_SendDataToServer(QByteArray data, quint8 outControlbyte);//发送数据

    //void s_InitOnce();



    void s_Message(QString msg);
    void s_Debug(QString msg);
    void s_Critical(QString msg);



public:
    explicit Game(QObject *parent = nullptr);
    virtual ~Game()
    {
        //m_pGameModel->TerminateGame(GameModel::Game_Status_Terminated, -1);
        sl_OverGame(Game_Status_Terminated, -88);
    }

    void quit(){}
    bool wait(int t){return 1;}
    void terminate(){}
    bool isRunning(){return true;}



//重载游戏框架
public:
    virtual int _InitOnce() Q_DECL_OVERRIDE  //进行初始化(仅1次)
    {
        int ret = GameModel::_InitOnce();
        if(ret != 0)
            return ret;


        m_pGameModel->m_bRunAtServer = false;

        return ret;
    }
    /*virtual int InitOnceInThread() Q_DECL_OVERRIDE //线程中初始化(1次)
    {
        return GameCore::InitOnceInThread();
    }
    */

    virtual int _OverGame(_GameStatus status = Game_Status_GameOver, qint32 code = 0) Q_DECL_OVERRIDE
    {
        //qDebug() << "Game.h GameOver!!!";
        return GameModel::_OverGame(status, code);
    }

    virtual int _GameInit(int sr = -1, QVariantMap param = QVariantMap()) Q_DECL_OVERRIDE
    {
        //m_mutexNet.tryLock();
        //releaseDataList();

        //m_Producer.init();

        //param["0"] = QVariant::fromValue<void*>(m_CommonGameData.m_listPets.at(0));

        qDebug() << "[GameGroup]GameInit";
        return GameModel::_GameInit(sr, param);

    }

    virtual GameModel::_GameStatus _TerminateGame(GameModel::_GameStatus status = GameModel::Game_Status_Terminated, qint32 code = 0) Q_DECL_OVERRIDE
    {
        return GameModel::_TerminateGame(status, code);
    }

protected:
    virtual GameModel::_GameStatus CheckGameOver() Q_DECL_OVERRIDE
    {
        return GameModel::CheckGameOver();
    }


//UI游戏框架

protected:
    /*/等待UI解锁进程
    virtual void WaitForUserAction() Q_DECL_OVERRIDE
    {
        //注意:
        //unlock状态下:unlock函数会出错;QWaitCondition::wait函数会出错
        //所以保持lock状态
        m_mutexUserAction.lock();
        if(gameStatus() != Game_Status_Continue)
        {
            m_mutexUserAction.unlock();
            return;
        }
        m_waitForUserAction.wait(&m_mutexUserAction);
        m_mutexUserAction.unlock();
        //qDebug()<<"m_mutexUserAction lock1!!!";
        //m_mutexUserAction.tryLock();  //立即返回是否已锁定(肯定会锁定)
        //m_waitForNet.wait(&m_mutexUserAction);
    }*/

    /*
    virtual void WaitForNet() Q_DECL_OVERRIDE
    {
        qDebug()<<"m_mutexNet lock0!!!";
        m_mutexNet.lock();
        qDebug()<<"m_mutexNet lock1!!!";
    }*/

//qml信号槽
public slots:
    /*Q_INVOKABLE* / virtual void sl_UserActionFinished() Q_DECL_OVERRIDE
    {
        //qDebug()<<"m_mutexUserAction unlock0!!!";
        //m_mutexUserAction.tryLock();    //防止多个数据包到来时多次unlock
        //m_mutexUserAction.unlock();
        m_mutexUserAction.lock();
        m_waitForUserAction.wakeAll();
        m_mutexUserAction.unlock();
        //qDebug()<<"m_mutexUserAction unlock1!!!";
        //m_waitForUserAction.wakeAll();
        //qDebug()<<"wakeALL!!";
    }*/
    /*
    virtual void netFinished() Q_DECL_OVERRIDE
    {
        //qDebug() << "netFinished线程:" << QThread::currentThreadId();
        //qDebug()<<"m_mutexNet tryLock unlock0!!!" <<QThread::currentThreadId();;
        m_mutexNet.tryLock();    //防止多个数据包到来时多次unlock
        m_mutexNet.unlock();
        //qDebug()<<"m_mutexNet tryLock unlock1!!!" << QThread::currentThreadId();;
        //m_waitForNet.wakeAll();
        //qDebug()<<"wakeALL!!";
    }*/






//重载游戏逻辑



//游戏其他函数
public slots:
    //游戏线程提交给主线程 发送数据
    void SendDataToServer(QByteArray& data, quint8 outControlbyte = TRANSMIT_GAME_TYPE);


    //qml调用,调试
    void sl_qml_DebugButton(int button, QVariant v);


//属性
public:

    QObject* gameModel()
    {
        return m_pGameModel;
    }

    QObject* socketInfo() const;

//测试
    QObjectList testList() const
    {
        return m_listTest;
    }

public:
//UI游戏框架
    //QWaitCondition需要已锁的QMutex才能wait,wait时会将QMutex unlock!!
    QWaitCondition  m_waitForUserAction;
    QMutex          m_mutexUserAction;
    //bool            m_bAction;      //是否可以Wake工作线程,其实也可以不用

    //QWaitCondition  m_waitForQuestion;
    //QWaitCondition  m_waitForNet;
    //QMutex          m_mutexQuestion;

//网络游戏框架
    //ProducerModel   m_Producer;
    TcpSocket       *m_pGameSocket;



public:
//游戏数据:
    Sqlite          *m_pSqliteDB;           //配置(Manager赋值)


    GameModel       *m_pGameModel;



//测试
    QObjectList     m_listTest;
};

//Q_DECLARE_METATYPE(GameCore::_GameStatus)

#endif //GAME_H
